package sandbox;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.joda.time.Duration;
import org.joda.time.Instant;

import sandbox.StateList.State;
import sandbox.TaskSet.Task;
import sandbox.WorkerSet.Worker;



public class KPtest {

	public static void main(String[] args) throws Exception {
		{
			WorkerSet.Worker[] workers = new WorkerSet.Worker[5];
			for (int i = 0; i < workers.length; i++)
				workers[i] = new WorkerSet().new Worker();
			WorkerSet.add(workers);
		}

		{
			TaskSet.Task[] tasks = new TaskSet.Task[10];
			for (int i = 0; i < tasks.length; i++) {
				Random r = new Random();
				tasks[i] = new TaskSet().new Task(r.nextInt(10), r.nextInt(10),
						new Duration(r.nextInt(10)));
			}
			TaskSet.add(tasks);
		}

		for (WorkerSet.Worker worker : WorkerSet.get())
			System.out.println(worker);

		for (TaskSet.Task task : TaskSet.get())
			System.out.println(task);

		Comparator<TaskSet.Task> taskComparator = new Comparator<TaskSet.Task>() {
			@Override
			public int compare(Task o1, Task o2) {
				int o1Inc = o1.getProfit() - o1.getCost();
				int o2Inc = o2.getProfit() - o2.getCost();
				return (o2Inc == 0) ? o1Inc : o1Inc / o2Inc;
			}
		};

		List<TaskSet.Task> tasksToBeDone = TaskSet.get(taskComparator);

		/*
		 * getting a list of possible decisions is not efficient that's why not
		 * implemented in initial phase
		 */

		while (tasksToBeDone.size() > 0) {
			State previousState = StateList.getLastState();
			Instant timeInstantNow = (previousState == null) ? new Instant(0)
					: previousState.nextStateTime();
			Set<Decision> decisionsTakenInPreviousStep = (previousState == null) ? null : previousState
					.getDecisionsTakenInThisState();
			Set<Decision> decisionsTakenInThisStep = new HashSet<Decision>();
			if (decisionsTakenInPreviousStep == null)
				for (Worker worker : WorkerSet.get()) {
					if (tasksToBeDone.size() > 0) {
						Decision d = new Decision(tasksToBeDone.get(0),worker,timeInstantNow
								.plus(tasksToBeDone.get(0).getDuration()));
						tasksToBeDone.remove(0);
						decisionsTakenInThisStep.add(d);
					}
				}
			else{
				for (Decision decision : decisionsTakenInPreviousStep) {
					if(decision.getWhenTheWorkFinishes().isAfter(timeInstantNow))
						decisionsTakenInThisStep.add(decision);
					else
					{
						if (tasksToBeDone.size() > 0) {
							Decision d = new Decision(tasksToBeDone.get(0),decision.getWorkerWhoPerformTheTask(),timeInstantNow
									.plus(tasksToBeDone.get(0).getDuration()));
							tasksToBeDone.remove(0);
							decisionsTakenInThisStep.add(d);
						}
					}
				}
			}
			new StateList().addState(timeInstantNow, decisionsTakenInThisStep);
		}
		
		for (State s : StateList.getFollowingStates()) {
			System.out.println(s);
		}

	}

}
